package com.tbit.uqbike.quartz;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.tbit.uqbike.object.pojo.Account;
import com.tbit.uqbike.object.pojo.MoneyData;
import com.tbit.uqbike.object.pojo.statistics.*;
import com.tbit.uqbike.object.pojo.vo.AreaVO;
import com.tbit.uqbike.service.base.OrderCumStaService;
import com.tbit.uqbike.service.base.RedisService;
import com.tbit.uqbike.service.base.impl.RedisServiceImpl;
import com.tbit.uqbike.webmanager.dao.core.*;
import com.tbit.uqbike.webmanager.dao.stat.*;
import com.tbit.uqbike.webmanager.util.LocalDateUtils;
import com.tbit.uqbike.webmanager.util.StringUtil;
import com.tbit.uqbike.webmanager.util.spring.SpringUtils;
import com.tbit.utils.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jing
 * @date 2020/11/1816:46
 * @Description:
 */
@Component
@Slf4j
public class FinancialStatisticsQuartz {
    public static ThreadLocal<List<Integer>> threadLocal = new ThreadLocal<>();
    public static ThreadLocal<List<Integer>> threadLocalByRegionId = new ThreadLocal<>();
    private static List<Integer> detects = null;
    private static List<Integer> detectsByRegionId = null;
    private static List<Account> accounts = null;
    private static List<Integer> regions = null;

    @Autowired
    private AccountDao accountDao;
    @Autowired
    private RideLogDao rideLogDao;
    @Autowired
    private RideCardDao rideCardDao;
    @Autowired
    private MemberFeeDao memberFeeDao;
    @Autowired
    private VipCardDao vipCardDao;
    @Autowired
    private RideOrderDayStaDao rideOrderDayStaDao;
    @Autowired
    private DepositOrderDayStaDao depositOrderDayStaDao;
    @Autowired
    private RideCardOrderDayStaDao rideCardOrderDayStaDao;
    @Autowired
    private VipCardOrderDayStaDao vipCardOrderDayStaDao;
    @Autowired
    private RedisService redisService;
    @Autowired
    private GeoRegionDao geoRegionDao;
    @Resource
    private RechargeOrderDayStaDao rechargeOrderDayStaDao;
    @Resource
    private UserAccountLogDao userAccountLogDao;
    @Autowired
    private ReconciliationDao reconciliationDao;
    @Autowired
    private GeoReMachineDao geoReMachineDao;
    @Autowired
    private MachineDao machineDao;

    public static void main(String[] args) {
        RedisService redisService = new RedisServiceImpl();
        redisService.incr(String.valueOf(123));
    }

    @Scheduled(cron = "0 0 4 * * ?")
    public void statisticalRideLog() {
        log.info("分区预统计开始执行");
        Map<String, Object> params = new HashMap<>(8);
        String toDay = DateTimeUtil.getNowTimeYMD();
        if (null == detectsByRegionId || detectsByRegionId.size() == 0) {
            /**查询所有分区id*/
            regions = geoRegionDao.getRegionId();
        }
        if (null == regions) {
            return;
        }
        log.info("卡和骑行订单开始统计,统计分区总数为：" + regions.size());
        long startTime = System.currentTimeMillis();
        //查询今天之前的各分区车辆数
        Map<Integer, Map> geoReMachineCountMap = geoReMachineDao.queryCountGroupByRegion(DateUtil.beginOfDay(new Date()));
        regions.forEach(regionId -> {
            /**删除前一天的key*/
            if (redisService.hasKey(DateTimeUtil.getYesterday() + "_" + regionId)) {
                redisService.del(DateTimeUtil.getYesterday() + "_" + regionId);
            }
            params.put("regionId", regionId);
            params.put("isCount", DateTimeUtil.getYesterdayHHMMSS(-1));
            /***获取昨天的开始时间*/
            params.put("startDt", DateTimeUtil.DateTimeToStringYMD(DateTimeUtil.addDay(new Date(), -1)));
            /**获取今天的开始时间*/
            params.put("endDt", DateTimeUtil.DateTimeToStringYMD(new Date()));

            /**按天统计骑行订单*/
            List<RideOrderDaySta> rideOrder = rideOrderDayStaDao.queryByMapAndRegionId(params);
            if (rideOrder.size() == 0) {
                /**查询骑行日统计的分区数据*/
                List<Map<String, Object>> ridelogs = rideLogDao.statByDayAndRegionId(params);
                if (!ridelogs.isEmpty()) {
                    //计算车均订单数和车均订单金额
                    ridelogs.forEach(a -> setMeanOrder(a, geoReMachineCountMap, regionId));
                    rideOrderDayStaDao.insertBatchByRegionId(ridelogs);
                }
                redisService.incrByRegionId(String.valueOf(regionId));
            } else {
                /**有数据则只计算前一天*/
                RideOrderDaySta rideOrderDaySta = rideOrder.get(0);
                /**判断预统计的时间是否是今天的时间*/
                if (!DateTimeUtil.formatDateYMD(rideOrderDaySta.getAddTime()).equals(toDay)) {
                    Map<String, Object> maps = rideLogDao.statYesterdayOrderByRegionId(params);
                    System.out.println(maps.toString());
                    if (!(0 == Integer.parseInt(String.valueOf(maps.get("money"))) && 0 == Integer.parseInt(String.valueOf(maps.get("num"))))) {
                        setMeanOrder(maps, geoReMachineCountMap, regionId);
                        rideOrderDayStaDao.insertByRegionId(maps);
                    } else {
                        rideOrderDaySta.setAddTime(new Date());
                        rideOrderDayStaDao.update(rideOrderDaySta);
                    }
                    redisService.incrByRegionId(String.valueOf(regionId));
                }
            }
        });
        log.info("区域余额统计耗时：" + (System.currentTimeMillis() - startTime) + "毫秒");
        if (null != regions) {
            regions.clear();
        }
        if (null != detectsByRegionId) {
            detectsByRegionId.clear();
        }
    }

    /**
     * 根据区域或分区获取车辆数量
     *
     * @param map 分组查询出来的map
     * @param id  区域或分区id
     * @return
     */
    private Integer getCountByMap(Map<Integer, Map> map, Integer id) {
        return map.get(id) == null ? 0 : Integer.parseInt(map.get(id).get("count").toString());
    }

    /**
     * 计算车均订单数和车均订单金额
     *
     * @param insertMap
     * @param machineCountMap
     * @param id
     */
    private void setMeanOrder(Map<String, Object> insertMap, Map<Integer, Map> machineCountMap, Integer id) {
        Integer countByMap = getCountByMap(machineCountMap, id);
        //车均订单数
        double meanOrderCount = 0;
        //车均订单金额
        double meanOrderMoney = 0;
        Integer num = Integer.valueOf(insertMap.get("num").toString());
        Integer money = Integer.valueOf(insertMap.get("money").toString());
        if (countByMap != 0) {
            //除数不能为0
            meanOrderCount = NumberUtil.div((double) num, (double) countByMap);
            meanOrderMoney = NumberUtil.div((double) money, (double) countByMap);
        }
        insertMap.put("meanOrderCount", meanOrderCount);
        insertMap.put("meanOrderMoney", meanOrderMoney);


    }

    @Scheduled(cron = "0 0 3 * * ?")
    public void statisticalData() {
        try {
            Map<String, Object> params = new HashMap<>(8);
            String toDay = DateTimeUtil.getNowTimeYMD();
            params.put("type", "3");
            if (null == detects || detects.size() == 0) {
                accounts = accountDao.getAccountByType(params);
            }
            params.clear();
            if (null != accounts && accounts.size() > 0) {
                detects = accounts.stream().map(Account::getAccountId).collect(Collectors.toList());
            }
            if (null == detects) {
                return;
            }
            log.info("卡和骑行订单开始统计,统计区域总数为：" + detects.size());
            //查询今天之前的各区域车辆数
            Map<Integer, Map> machineCountMap = machineDao.queryCountGroupByAccountId(DateUtil.beginOfDay(new Date()));
            long startTime = System.currentTimeMillis();
            detects.forEach(account -> {
                /**删除前一天的缓存*/
                if (redisService.hasKey(DateTimeUtil.getYesterday() + "." + account)) {
                    redisService.del(DateTimeUtil.getYesterday() + "." + account);
                }
                params.put("accountId", account);
                params.put("isCount", DateTimeUtil.getYesterdayHHMMSS(-1));
                /***获取昨天的开始时间*/
                params.put("startDt", DateTimeUtil.DateTimeToStringYMD(DateTimeUtil.addDay(new Date(), -1)));
                /**获取今天的开始时间*/
                params.put("endDt", DateTimeUtil.DateTimeToStringYMD(new Date()));
                /**
                 *
                 *统计骑行总订单
                 *
                 * */
                OrderCumStaService orderCumStaService = SpringUtils.getBean(OrderCumStaService.class);
                List<OrderCumSta> order = orderCumStaService.getByAccountId(params);
                if (order.size() == 0 || null == order.get(0)) {
                    MoneyData rideLog = rideLogDao.statMoney(params);
                    rideLog.setAccountId(account);
                    orderCumStaService.insert(new OrderCumSta(rideLog, 0));
                    redisService.incr(String.valueOf(account));
                } else {
                    /**如果更新时间和今天时间一致就不更新*/
                    if (!DateTimeUtil.formatDateYMD(order.get(0).getUpdateTime()).equals(toDay)) {
                        Map<String, Object> maps = rideLogDao.statYesterdayOrderByRegionId(params);
                        maps.put("type", "0");
                        orderCumStaService.updateByMap(maps);
                        redisService.incr(String.valueOf(account));
                    }
                }
                /**按天统计骑行订单*/
                List<RideOrderDaySta> rideOrder = rideOrderDayStaDao.queryByMap(params);
                if (rideOrder.size() == 0) {
                    /**不存在数据即从按天统计到昨天*/
                    List<Map<String, Object>> ridelogs = rideLogDao.statByDay(params);
                    if (!ridelogs.isEmpty()) {
                        //计算车均订单数和车均订单金额
                        ridelogs.forEach(a -> setMeanOrder(a, machineCountMap, account));
                        rideOrderDayStaDao.insertBatch(ridelogs);
                    }
                    redisService.incr(String.valueOf(account));
                } else {
                    /**有数据则只计算前一天*/
                    RideOrderDaySta rideOrderDaySta = rideOrder.get(0);
                    if (!DateTimeUtil.formatDateYMD(rideOrderDaySta.getAddTime()).equals(toDay)) {
                        Map<String, Object> maps = rideLogDao.statYesterdayOrder(params);
                        if (!(0 == Integer.parseInt(String.valueOf(maps.get("money"))) && 0 == Integer.parseInt(String.valueOf(maps.get("num"))))) {
                            ////计算车均订单数和车均订单金额
                            setMeanOrder(maps, machineCountMap, account);
                            rideOrderDayStaDao.insertByMap(maps);
                        } else {
                            rideOrderDaySta.setAddTime(new Date());
                            rideOrderDayStaDao.update(rideOrderDaySta);
                        }
                        redisService.incr(String.valueOf(account));
                    }
                }
                /**
                 *
                 *统计免押卡
                 *
                 * */
                if (order.size() == 0 || null == order.get(1)) {
                    MoneyData mem = memberFeeDao.getTotalMoney(params);
                    mem.setAccountId(account);
                    orderCumStaService.insert(new OrderCumSta(mem, 1));
                    redisService.incr(String.valueOf(account));
                } else {
                    /**如果更新时间和今天时间一样就不更新*/
                    if (!DateTimeUtil.formatDateYMD(order.get(1).getUpdateTime()).equals(toDay)) {
                        Map<String, Object> maps = memberFeeDao.statYesterdayMem(params);
                        maps.put("type", "1");
                        orderCumStaService.updateByMap(maps);
                        redisService.incr(String.valueOf(account));
                    }
                }
                /**按天统计免押卡*/
                List<DepositOrderDaySta> deposits = depositOrderDayStaDao.queryByMap(params);
                if (deposits.size() == 0) {
                    /**不存在数据即从按天统计到昨天*/
                    List<Map<String, Object>> depositOrders = memberFeeDao.statByDay(params);
                    if (!depositOrders.isEmpty()) {
                        depositOrderDayStaDao.insertBatch(depositOrders);
                    }
                    redisService.incr(String.valueOf(account));
                } else {
                    /**有数据则只计算前一天*/
                    DepositOrderDaySta depositOrderDaySta = deposits.get(0);
                    if (!DateTimeUtil.formatDateYMD(depositOrderDaySta.getAddTime()).equals(toDay)) {
                        Map<String, Object> maps = memberFeeDao.statYesterdayMem(params);
                        if (!(new Double(String.valueOf(maps.get("money"))).equals(0.0) && 0 == Integer.parseInt(String.valueOf(maps.get("num"))))) {
                            depositOrderDayStaDao.insertByMap(maps);
                        } else {
                            depositOrderDaySta.setAddTime(new Date());
                            depositOrderDayStaDao.update(depositOrderDaySta);
                        }
                        redisService.incr(String.valueOf(account));
                    }
                }

                /**
                 *
                 *统计骑行卡
                 *
                 * */
                if (order.size() == 0 || null == order.get(2)) {
                    MoneyData rideCard = rideCardDao.getTotalMoney(params);
                    rideCard.setAccountId(account);
                    orderCumStaService.insert(new OrderCumSta(rideCard, 2));
                    redisService.incr(String.valueOf(account));
                } else {
                    /**如果更新时间和今天时间一直就不更新*/
                    if (!DateTimeUtil.formatDateYMD(order.get(2).getUpdateTime()).equals(toDay)) {
                        Map<String, Object> maps = rideCardDao.statYesterdayRideCard(params);
                        maps.put("type", "2");
                        orderCumStaService.updateByMap(maps);
                        redisService.incr(String.valueOf(account));
                    }
                }
                /**按天统计骑行卡*/
                List<RideCardOrderDaySta> rides = rideCardOrderDayStaDao.queryByMap(params);
                if (rides.size() == 0) {
                    /**不存在数据即从按天统计到昨天*/
                    List<Map<String, Object>> rideCards = rideCardDao.statByDay(params);
                    if (!rideCards.isEmpty()) {
                        rideCardOrderDayStaDao.insertBatch(rideCards);
                    }
                    redisService.incr(String.valueOf(account));
                } else {
                    /**有数据则只计算前一天*/
                    RideCardOrderDaySta rideCardOrderDaySta = rides.get(0);
                    if (!DateTimeUtil.formatDateYMD(rideCardOrderDaySta.getAddTime()).equals(toDay)) {
                        Map<String, Object> maps = rideCardDao.statYesterdayRideCard(params);
                        if (!(maps.get("money").equals(new BigDecimal("0.00")) && 0 == Integer.parseInt(String.valueOf(maps.get("num"))))) {
                            rideCardOrderDayStaDao.insertByMap(maps);
                        } else {
                            rideCardOrderDaySta.setAddTime(new Date());
                            rideCardOrderDayStaDao.update(rideCardOrderDaySta);
                        }
                        redisService.incr(String.valueOf(account));
                    }
                }

                /**
                 *
                 *统计vip卡
                 *
                 * */
                if (order.size() == 0 || null == order.get(3)) {
                    MoneyData vipCard = vipCardDao.getTotalMoney(params);
                    vipCard.setAccountId(account);
                    orderCumStaService.insert(new OrderCumSta(vipCard, 3));
                    redisService.incr(String.valueOf(account));
                } else {
                    /**如果更新时间和今天时间一直就不更新*/
                    if (!DateTimeUtil.formatDateYMD(order.get(3).getUpdateTime()).equals(toDay)) {
                        Map<String, Object> maps = vipCardDao.statYesterdayVipCard(params);
                        maps.put("type", "3");
                        orderCumStaService.updateByMap(maps);
                        redisService.incr(String.valueOf(account));
                    }
                }
                /**按天统计vip卡*/
                List<VipCardOrderDaySta> vips = vipCardOrderDayStaDao.queryByMap(params);
                if (vips.size() == 0) {
                    /**不存在数据即从按天统计到昨天*/
                    List<Map<String, Object>> rideCards = vipCardDao.statByDay(params);
                    if (!rideCards.isEmpty()) {
                        vipCardOrderDayStaDao.insertBatch(rideCards);
                    }
                    redisService.incr(String.valueOf(account));
                } else {
                    /**有数据则只计算前一天*/
                    VipCardOrderDaySta vipCardOrderDaySta = vips.get(0);
                    if (!DateTimeUtil.formatDateYMD(vipCardOrderDaySta.getAddTime()).equals(toDay)) {
                        Map<String, Object> maps = vipCardDao.statYesterdayVipCard(params);
                        if (!(0 == Integer.parseInt(String.valueOf(maps.get("money"))) && 0 == Integer.parseInt(String.valueOf(maps.get("num"))))) {
                            vipCardOrderDayStaDao.insertByMap(maps);
                        } else {
                            vipCardOrderDaySta.setAddTime(new Date());
                            vipCardOrderDayStaDao.update(vipCardOrderDaySta);
                        }
                        redisService.incr(String.valueOf(account));
                    }
                }
            });
            log.info("区域余额统计耗时：" + (System.currentTimeMillis() - startTime) + "毫秒");
        }catch (Exception e){
            log.error("区域预统计执行异常", e);
        }finally {
            //清空区域id 确保新增的区域能进行预统计
            Optional.ofNullable(accounts).ifPresent(List::clear);
            Optional.ofNullable(detects).ifPresent(List::clear);
        }
    }

    public void statisticalData123(String accountIds, String startDate, String endDate) {
        Map<String, Object> params = new HashMap<>(8);
        List<Integer> detects = StringUtil.getIntegerList(accountIds);
        detects.forEach(account -> {
            params.put("accountId", account);
            /***获取昨天的开始时间*/
            params.put("startDate", startDate);
            /**获取今天的开始时间*/
            params.put("endDate", endDate);

            log.info("params===========" + params);
            /**不存在数据即从按天统计到昨天*/
            List<Map<String, Object>> maps = rideLogDao.selectLog(params);
            if (!maps.isEmpty()) {
                rideOrderDayStaDao.insertBatch(maps);
            }

            /**不存在数据即从按天统计到昨天*/
            List<Map<String, Object>> depositOrders = memberFeeDao.statByDayLog(params);
            if (!depositOrders.isEmpty()) {
                depositOrderDayStaDao.insertBatch(depositOrders);
            }

            List<Map<String, Object>> rideCardMaps = rideCardDao.statByDayLog(params);
            if (!rideCardMaps.isEmpty()) {
                rideCardOrderDayStaDao.insertBatch(rideCardMaps);
            }

            List<Map<String, Object>> vipCardMaps = vipCardDao.statByDayLog(params);
            if (!vipCardMaps.isEmpty()) {
                vipCardOrderDayStaDao.insertBatch(vipCardMaps);
            }

        });
    }

    /**
     * 根据品牌id和时间重新进行预统计
     * @param brandId 品牌id
     * @param startDate 开始时间
     * @param endDate 结束时间
     */
    public void statisticalDataByBrandId(Integer brandId, Date startDate, Date endDate){
        try {
            //获取品牌下所有区域
            List<Integer> accountIdList = accountDao.getAreaByBrandId(brandId).stream().map(AreaVO::getAccountId).collect(Collectors.toList());

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String st = simpleDateFormat.format(startDate);
            String et = simpleDateFormat.format(endDate);
            log.info("开始执行预统计,区域数量:{},起始时间:{},结束时间:{}", accountIdList.size(), startDate, endDate);
            //删除品牌下区域的预统计
            deleteById(accountIdList, st, et);

            Map<String, Object> requestBody = new HashMap<>();

            for (Integer accountId : accountIdList) {
                requestBody.put("accountId", accountId);
                requestBody.put("startDate", startDate);
                requestBody.put("endDate", endDate);

                //统计骑行订单
                List<Map<String, Object>> rideLogList = rideLogDao.selectLog(requestBody);
                if (CollectionUtil.isNotEmpty(rideLogList)) {
                    rideOrderDayStaDao.insertBatch(rideLogList);
                }
                //统计免押卡
                List<Map<String, Object>> memberFeeList = memberFeeDao.statByDayLog(requestBody);
                if (CollectionUtil.isNotEmpty(memberFeeList)) {
                    depositOrderDayStaDao.insertBatch(memberFeeList);
                }
                //统计骑行卡
                List<Map<String, Object>> rideCardList = rideCardDao.statByDayLog(requestBody);
                if (CollectionUtil.isNotEmpty(rideCardList)) {
                    rideCardOrderDayStaDao.insertBatch(rideCardList);
                }
                //统计会员卡
                List<Map<String, Object>> vipCardList = vipCardDao.statByDayLog(requestBody);
                if (CollectionUtil.isNotEmpty(vipCardList)) {
                    vipCardOrderDayStaDao.insertBatch(vipCardList);
                }
                requestBody.clear();
            }
        }catch (Exception e){
            log.error("品牌预统计执行异常", e);
        }

    }

    /**
     * 删除区域对应时间区间的预统计数据
     */
    private void deleteById(List<Integer> accountIdList, String st, String et) {
        log.info("开始删除{}-{}预统计数据", st, et);
        long s = System.currentTimeMillis();
        rideOrderDayStaDao.deleteById(accountIdList, st, et);
        depositOrderDayStaDao.deleteById(accountIdList, st, et);
        rideCardOrderDayStaDao.deleteById(accountIdList, st, et);
        vipCardOrderDayStaDao.deleteById(accountIdList, st, et);
        log.info("删除结束{}-{}预统计数据,耗时:{}秒", st, et, (System.currentTimeMillis() - s) / 100);
    }


    public void detect() {
        if (true) {
            return;
        }
        /**每天早上六点之前和晚上11点之后不执行检测*/
        ZonedDateTime dateTime = ZonedDateTime.now(Clock.systemDefaultZone());
        ZonedDateTime startTime = ZonedDateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 6, 0, 0, 0, ZoneId.systemDefault());
        ZonedDateTime endTime = ZonedDateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 23, 0, 0, 0, ZoneId.systemDefault());
        if (dateTime.isAfter(startTime) && dateTime.isBefore(endTime)) {
            synchronized (this) {
                List<Integer> list = threadLocal.get();
                detect(dateTime, list);
                threadLocal.remove();
            }
        }
    }

    /**
     * 3.0.0新增，检测分区订单预统计
     */
    public void detectByRegionId() {
        /**每天早上六点之前和晚上11点之后不执行检测*/
        ZonedDateTime dateTime = ZonedDateTime.now(Clock.systemDefaultZone());
        ZonedDateTime startTime = ZonedDateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 6, 0, 0, 0, ZoneId.systemDefault());
        ZonedDateTime endTime = ZonedDateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 23, 0, 0, 0, ZoneId.systemDefault());
        if (dateTime.isAfter(startTime) && dateTime.isBefore(endTime)) {
            synchronized (this) {
                List<Integer> listRegionIds = threadLocalByRegionId.get();
                detectByRegionIds(dateTime, listRegionIds);
                threadLocalByRegionId.remove();
            }
        }
    }

    @Scheduled(cron = "0 30 4 * * ?")
    public void onlineDetect() {
        log.info("区域余额统计检查");
        ZonedDateTime now = ZonedDateTime.now(Clock.systemDefaultZone());
        Map<String, Object> params = new HashMap<>(8);
        params.put("type", "3");
        List<Integer> ids = null;
        if (null == detects || detects.size() == 0) {
            ids = accountDao.getAccountByType(params).stream().map(Account::getAccountId).collect(Collectors.toList());
        }
        detect(now, ids);
    }

    public void detect(ZonedDateTime now, List<Integer> list) {
        if (true) {
            return;
        }
        if (null != list && list.size() > 0) {
            Iterator<Integer> iterator = list.iterator();
            while (iterator.hasNext()) {
                Integer account = iterator.next();
                String redisKey = redisService.get(LocalDateUtils.format(now, LocalDateUtils.DATE_PATTERN) + "." + account);
                if (null != redisKey && 8 <= Integer.parseInt(redisKey)) {
                    iterator.remove();
                }
            }
            if (!list.isEmpty()) {
                detects = list;
                statisticalData();
            }
        }
    }

    @Scheduled(cron = "0 30 5 * * ?")
    public void onlineDetectByRegion() {
        log.info("分区余额统计检查");
        ZonedDateTime now = ZonedDateTime.now(Clock.systemDefaultZone());
        List<Integer> regions = null;
        if (null == detectsByRegionId || detectsByRegionId.size() == 0) {
            regions = geoRegionDao.getRegionId();
        }
        detectByRegionIds(now, regions);
    }

    /**
     * 3.0.0新增，检测分区订单预统计
     */
    public void detectByRegionIds(ZonedDateTime now, List<Integer> listRegionIds) {
        if (null != listRegionIds && listRegionIds.size() > 0) {
            /**将传进来的分区id拼接，查询redis中是否有这个key*/
            Iterator<Integer> iteratorRegionId = listRegionIds.iterator();
            while (iteratorRegionId.hasNext()) {
                Integer regionId = iteratorRegionId.next();
                String redisKey = redisService.get(LocalDateUtils.format(now, LocalDateUtils.DATE_PATTERN) + "_" + regionId);
                if (null != redisKey && 1 <= Integer.parseInt(redisKey)) {
                    iteratorRegionId.remove();
                }
            }
            if (!listRegionIds.isEmpty()) {
                detectsByRegionId = listRegionIds;
                statisticalRideLog();
            }
        }
    }

    public void batchDelRedis() {
        batchDelRedis(null);
    }

    public void batchDelRedis(String day) {
        Map<String, Object> params = new HashMap<>(2);
        String toDay;
        if (null == day) {
            toDay = DateTimeUtil.getNowTimeYMD();
        } else {
            toDay = day;
        }
        params.put("type", "3");
        List<Account> ids = accountDao.getAccountByType(params);
        if (null != ids && ids.size() > 0) {
            ids.stream().forEach(account -> {
                boolean flag = redisService.hasKey(toDay + "." + account.getAccountId());
                if (flag) {
                    redisService.del(toDay + "." + account.getAccountId());
                    log.info("删除缓存" + toDay + "." + account.getAccountId());
                }
            });
        }
    }
}

